package jnpf.onlinedev.service.impl;

import jnpf.base.entity.VisualdevEntity;
import jnpf.base.service.DblinkService;
import jnpf.base.util.VisualUtils;
import jnpf.database.entity.DbLinkEntity;
import jnpf.database.util.JdbcUtil;
import jnpf.engine.util.FormCloumnUtil;
import jnpf.exception.DataException;
import jnpf.model.FormAllModel;
import jnpf.model.FormEnum;
import jnpf.model.FormMastTableModel;
import jnpf.model.RecursionForm;
import jnpf.model.visiual.FormDataModel;
import jnpf.model.visiual.TableModel;
import jnpf.model.visiual.fields.FieLdsModel;
import jnpf.onlinedev.model.VisualdevModelDataInfoVO;
import jnpf.onlinedev.service.VisualDevInfoService;
import jnpf.onlinedev.util.onlineDevUtil.OnlineDevInfoUtils;
import jnpf.onlinedev.util.onlineDevUtil.OnlinePublicUtils;
import jnpf.util.JsonUtil;
import jnpf.util.JsonUtilEx;
import jnpf.util.StringUtil;
import lombok.Cleanup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


/**
 *
 *
 * @author JNPF开发平台组
 * @version V3.2
 * @copyright 引迈信息技术有限公司（https://www.jnpfsoft.com）
 * @date  2021/10/26
 */
@Service
public class VisualDevInfoServiceImpl implements VisualDevInfoService {

	@Autowired
	private DblinkService dblinkService;
	@Override
	public VisualdevModelDataInfoVO getEditDataInfo(String id, VisualdevEntity visualdevEntity) {

		Map<String,Object> allDataMap = new HashMap<>();
		FormDataModel formData = JsonUtil.getJsonToBean(visualdevEntity.getFormData(), FormDataModel.class);
		List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
		List<TableModel> tableModelList = JsonUtil.getJsonToList(visualdevEntity.getTables(),TableModel.class);
		RecursionForm recursionForm =new RecursionForm();
		recursionForm.setList(list);
		recursionForm.setTableModelList(tableModelList);
		List<FormAllModel> formAllModel = new ArrayList<>();
		FormCloumnUtil.recursionForm(recursionForm, formAllModel);
		//form的属性
		List<FormAllModel> mast = formAllModel.stream().filter(t -> FormEnum.mast.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
		List<FormAllModel> table = formAllModel.stream().filter(t -> FormEnum.table.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
		List<FormAllModel> mastTable = formAllModel.stream().filter(t-> FormEnum.mastTable.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());

		TableModel mainTable = tableModelList.stream().filter(t -> t.getTypeId().equals("1")).findFirst().orElse(null);

		DbLinkEntity linkEntity = dblinkService.getInfo(visualdevEntity.getDbLinkId());
		try {
			@Cleanup Connection conn = VisualUtils.getDataConn(linkEntity);
			//获取主键
			String pKeyName = VisualUtils.getpKey(conn, mainTable.getTable());
			//主表所有数据
			String mainAllTableSql = "select *" +  " from "+ mainTable.getTable() + " where " + pKeyName + "='" + id + "'";
			Map<String, Object> mainAllMap = OnlinePublicUtils.mapKeyToLower(JdbcUtil.queryOne(conn, mainAllTableSql)) ;
			//主表
			String mainTableFields = mast.stream().filter(m -> StringUtil.isNotEmpty(m.getFormColumnModel().getFieLdsModel().getVModel()))
					.map(s -> s.getFormColumnModel().getFieLdsModel().getVModel()).collect(Collectors.joining(","));
			String mainTableSql = "select " +mainTableFields+  " from "+ mainTable.getTable() + " where " + pKeyName + "='" + id + "'";
			Map<String, Object> mainMap = JdbcUtil.queryOne(conn, mainTableSql);
			//转换主表里的数据
			List<FieLdsModel> mainFieldList = mast.stream().filter(m -> StringUtil.isNotEmpty(m.getFormColumnModel().getFieLdsModel().getVModel()))
					.map(t -> t.getFormColumnModel().getFieLdsModel()).collect(Collectors.toList());
			mainMap = OnlineDevInfoUtils.swapDataInfoType(mainFieldList, OnlinePublicUtils.mapKeyToLower(mainMap));
			allDataMap.putAll(mainMap);

			//列表子表
			Map<String, List<FormMastTableModel>> groupByTableNames = mastTable.stream().map(mt -> mt.getFormMastTableModel()).collect(Collectors.groupingBy(ma -> ma.getTable()));
			Iterator<Map.Entry<String, List<FormMastTableModel>>> entryIterator = groupByTableNames.entrySet().iterator();
			while (entryIterator.hasNext()){
				Map.Entry<String, List<FormMastTableModel>> next = entryIterator.next();
				String childTableName =  next.getKey();
				List<FormMastTableModel> childMastTableList = next.getValue();
				TableModel childTableModel = tableModelList.stream().filter(t -> t.getTable().equals(childTableName)).findFirst().orElse(null);
				String childFields =childMastTableList.stream().map(m -> m.getField()).collect(Collectors.joining(","));
				String relationValue = String.valueOf(mainAllMap.get(childTableModel.getRelationField().toLowerCase()));
				String childSql = "select " +  childFields + " from "+ childTableName + " where " + childTableModel.getTableField() + "='" + relationValue + "'";
				Map<String, Object> soloDataMap =JdbcUtil.queryOne(conn, childSql);
				Map<String, Object> renameKeyMap = new HashMap<>();
				for (Map.Entry entry : soloDataMap.entrySet()){
					FormMastTableModel model = childMastTableList.stream().filter(child -> child.getField().equalsIgnoreCase(String.valueOf(entry.getKey()))).findFirst().orElse(null);
					renameKeyMap.put(model.getVModel(),entry.getValue());
				}
				List<FieLdsModel> columnChildFields = childMastTableList.stream().map(cl -> cl.getMastTable().getFieLdsModel()).collect(Collectors.toList());
				renameKeyMap =OnlineDevInfoUtils.swapDataInfoType(columnChildFields, OnlinePublicUtils.mapKeyToLower(renameKeyMap));
				allDataMap.putAll(renameKeyMap);
			}

			//设计子表
			table.stream().map(t->t.getChildList()).forEach(
					t1->{
						 String childTableName = t1.getTableName();
						TableModel tableModel = tableModelList.stream().filter(tm -> tm.getTable().equals(childTableName)).findFirst().orElse(null);
						String childFields = t1.getChildList().stream().map(t2 -> t2.getFieLdsModel().getVModel()).collect(Collectors.joining(","));
						String relationValue = String.valueOf(mainAllMap.get(tableModel.getRelationField().toLowerCase()));
						String childSql = "select " +  childFields + " from "+ childTableName + " where " + tableModel.getTableField() + "='" + relationValue + "'";
						try {
							List<Map<String, Object>> childMapList = JdbcUtil.queryList(conn, childSql);
							List<FieLdsModel> childFieldModels = t1.getChildList().stream().map(t2 -> t2.getFieLdsModel()).collect(Collectors.toList());
							childMapList=childMapList.stream().map(c1-> {
								try {
									return OnlineDevInfoUtils.swapDataInfoType(childFieldModels, OnlinePublicUtils.mapKeyToLower(c1));
								} catch (Exception e) {
									e.printStackTrace();
								}
								return c1;
							}).collect(Collectors.toList());
							Map<String, Object> childMap = new HashMap<>(1);
							childMap.put(t1.getTableModel(),childMapList);
							allDataMap.putAll(childMap);
						} catch (DataException e) {
							e.printStackTrace();
						}
					}
			);
		} catch (SQLException | DataException | ParseException | IOException sqlException) {
			sqlException.printStackTrace();
		}
		VisualdevModelDataInfoVO vo = new VisualdevModelDataInfoVO();
		vo.setId(id);
		vo.setData(JsonUtilEx.getObjectToString(allDataMap));
		return vo;
	}

	@Override
	public VisualdevModelDataInfoVO getDetailsDataInfo(String id, VisualdevEntity visualdevEntity) {
		Map<String,Object> allDataMap = new HashMap<>();
		FormDataModel formData = JsonUtil.getJsonToBean(visualdevEntity.getFormData(), FormDataModel.class);
		List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
		List<TableModel> tableModelList = JsonUtil.getJsonToList(visualdevEntity.getTables(),TableModel.class);
		RecursionForm recursionForm =new RecursionForm();
		recursionForm.setList(list);
		recursionForm.setTableModelList(tableModelList);
		List<FormAllModel> formAllModel = new ArrayList<>();
		FormCloumnUtil.recursionForm(recursionForm, formAllModel);
		//form的属性
		List<FormAllModel> mast = formAllModel.stream().filter(t -> FormEnum.mast.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
		List<FormAllModel> table = formAllModel.stream().filter(t -> FormEnum.table.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
		List<FormAllModel> mastTable = formAllModel.stream().filter(t-> FormEnum.mastTable.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());

		TableModel mainTable = tableModelList.stream().filter(t -> t.getTypeId().equals("1")).findFirst().orElse(null);

		DbLinkEntity linkEntity = dblinkService.getInfo(visualdevEntity.getDbLinkId());
		try {
			@Cleanup Connection conn = VisualUtils.getDataConn(linkEntity);
			//获取主键
			String pKeyName = VisualUtils.getpKey(conn, mainTable.getTable());
			//主表所有数据
			String mainAllTableSql = "select *" +  " from "+ mainTable.getTable() + " where " + pKeyName + "='" + id + "'";
			Map<String, Object> mainAllMap = OnlinePublicUtils.mapKeyToLower(JdbcUtil.queryOne(conn, mainAllTableSql)) ;
			//主表
			String mainTableFields = mast.stream().filter(m -> StringUtil.isNotEmpty(m.getFormColumnModel().getFieLdsModel().getVModel()))
					.map(s -> s.getFormColumnModel().getFieLdsModel().getVModel()).collect(Collectors.joining(","));
			String mainTableSql = "select " +mainTableFields+  " from "+ mainTable.getTable() + " where " + pKeyName + "='" + id + "'";
			Map<String, Object> mainMap = JdbcUtil.queryOne(conn, mainTableSql);
			//转换主表里的数据
			List<FieLdsModel> mainFieldList = mast.stream().filter(m -> StringUtil.isNotEmpty(m.getFormColumnModel().getFieLdsModel().getVModel()))
					.map(t -> t.getFormColumnModel().getFieLdsModel()).collect(Collectors.toList());
			mainMap =  OnlinePublicUtils.mapKeyToLower(mainMap);
			mainMap=OnlineDevInfoUtils.swapTableDataInfo(mainFieldList,mainMap,visualdevEntity.getId());
			allDataMap.putAll(mainMap);

			//列表子表
			Map<String, List<FormMastTableModel>> groupByTableNames = mastTable.stream().map(mt -> mt.getFormMastTableModel()).collect(Collectors.groupingBy(ma -> ma.getTable()));
			Iterator<Map.Entry<String, List<FormMastTableModel>>> entryIterator = groupByTableNames.entrySet().iterator();
			while (entryIterator.hasNext()){
				Map.Entry<String, List<FormMastTableModel>> next = entryIterator.next();
				String childTableName =  next.getKey();
				List<FormMastTableModel> childMastTableList = next.getValue();
				TableModel childTableModel = tableModelList.stream().filter(t -> t.getTable().equals(childTableName)).findFirst().orElse(null);
				String childFields =childMastTableList.stream().map(m -> m.getField()).collect(Collectors.joining(","));
				String relationValue = String.valueOf(mainAllMap.get(childTableModel.getRelationField().toLowerCase()));
				String childSql = "select " +  childFields + " from "+ childTableName + " where " + childTableModel.getTableField() + "='" + relationValue + "'";
				Map<String, Object> soloDataMap =JdbcUtil.queryOne(conn, childSql);
				Map<String, Object> renameKeyMap = new HashMap<>();
				for (Map.Entry entry : soloDataMap.entrySet()){
					FormMastTableModel model = childMastTableList.stream().filter(child -> child.getField().equalsIgnoreCase(String.valueOf(entry.getKey()))).findFirst().orElse(null);
					renameKeyMap.put(model.getVModel(),entry.getValue());
				}
				List<FieLdsModel> columnChildFields = childMastTableList.stream().map(cl -> cl.getMastTable().getFieLdsModel()).collect(Collectors.toList());
				renameKeyMap = OnlinePublicUtils.mapKeyToLower(renameKeyMap);
				renameKeyMap=OnlineDevInfoUtils.swapTableDataInfo(columnChildFields,renameKeyMap,visualdevEntity.getId());
				allDataMap.putAll(renameKeyMap);
			}

			//设计子表
			table.stream().map(t->t.getChildList()).forEach(
					t1->{
						String childTableName = t1.getTableName();
						TableModel tableModel = tableModelList.stream().filter(tm -> tm.getTable().equals(childTableName)).findFirst().orElse(null);
						String childFields = t1.getChildList().stream().map(t2 -> t2.getFieLdsModel().getVModel()).collect(Collectors.joining(","));
						String relationValue = String.valueOf(mainAllMap.get(tableModel.getRelationField().toLowerCase()));
						String childSql = "select " +  childFields + " from "+ childTableName + " where " + tableModel.getTableField() + "='" + relationValue + "'";
						try {
							List<Map<String, Object>> childMapList = JdbcUtil.queryList(conn, childSql);
							List<FieLdsModel> childFieldModels = t1.getChildList().stream().map(t2 -> t2.getFieLdsModel()).collect(Collectors.toList());
							childMapList=childMapList.stream().map(c1->OnlinePublicUtils.mapKeyToLower(c1)).collect(Collectors.toList());
							List<Map<String, Object>> finalChildMapList = new ArrayList<>();
							for (Map<String, Object> map :childMapList){
								finalChildMapList.add(OnlineDevInfoUtils.swapChildTableDataInfo(childFieldModels,map));
							}
							Map<String, Object> childMap = new HashMap<>(1);
							childMap.put(t1.getTableModel(),finalChildMapList);
							allDataMap.putAll(childMap);
						} catch (DataException e) {
							e.printStackTrace();
						}
					}
			);
		} catch (SQLException | DataException sqlException) {
			sqlException.printStackTrace();
		}catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		VisualdevModelDataInfoVO vo = new VisualdevModelDataInfoVO();
		vo.setId(id);
		vo.setData(JsonUtilEx.getObjectToString(allDataMap));
		return vo;
	}
}
